#include <common.h>
#include "syscall.h"
#include <fs.h>
#include <sys/time.h>

void do_syscall(Context *c) {
  int my_gettimeofday(struct timeval * tv, struct timezone * tz);
  uintptr_t a[4];
  a[0] = c->GPR1;
  a[1] = c->GPR2;
  a[2] = c->GPR3;
  a[3] = c->GPR4;
  int ret;
 // Log("pc:%lx,DO_SYSCALL: Type:%d,return/GPRx/a0/GPR2 %d, GPR3/a1:%d,a2:%d",c->mepc,a[0],a[1],a[2],a[3]);
  switch (a[0]) {
    case 1  : c->GPRx = 0; yield();break;                  //sys_yield
    case 0  : halt(a[1]);break;   	                   //sys_exit
    case 2  : ret = fs_open((const char *)a[1],a[2],a[3]); //sys_open
	      c->GPRx = ret;
	      break;
    case 3  : ret = fs_read(a[1],(void *)a[2],a[3]);       //sys_read
	      c->GPRx = ret;
	      break;
    case 4  :/*	 if(file_table[a[1]].write != NULL){                  //sys_write
                 int l = 0;
		 while(l<a[3]){
		   putch(*(char *)(a[2]+l));
		   l++;
		 }
		 c->GPRx = l;
		 file_table[a[1]].write((void *)a[2],0,a[3]);
		 Log("Write");
	      }
	      else{*/
	        ret = fs_write(a[1],(void *)a[2],a[3]);
	        c->GPRx = ret;
//	   Log("DO_SYSCALL: Fwrite,fd:%d,len%d",a[1],a[3]);
	     // }
	        break;
    case 7 : ret = fs_close(a[1]);                //sys_close
	     c->GPRx = ret;
	     break;
    case 8 : ret = fs_lseek(a[1],a[2],a[3]);      //sys_lseek 
	     c->GPRx = ret;
//	     Log("lseek");
	     break;
    case 9 : 
	     //Log("pc:%lx,DO_SYSCALL:BRK, old_break:%lx,program_break:%lx,increment:%lx",c->mepc,a[2],a[1],a[3]);
//	     if(a[3] >= 0x5000000)c->GPRx = -1;
//	     else 
		     c->GPRx = 0;
	     break;                               //sys_brk 
    case 19 :my_gettimeofday((struct timeval *)a[1], (struct timezone *)a[2]);
	     c->GPRx = 0;
	     break;
    default : panic("Unhandled syscall ID = %d", a[0]);
  }
 
}
